!lm10
!rm76
Poor Man's Disassembler.....................James O. Church

I wanted a quick and cheap way to get machine language code into the S-C Assembler II Version 4.0, via a text file.  I didn't need labels or other automatic features like those $25-$30 Two-Pass Disassemblers have.  Or at least not badly enough to pay the price and wait for delivery.

There is a fundamental disassembler in the Apple Monitor ROM, which the "L" command invokes.  The problems with it are that it only writes on the screen (not on a text file), and it is not in the correct format for the assembler to use.  It has too many spaces between the opcode and operand fields, and there is and address rather than a line number at the beginning of each line.

I wrote a program in Applesoft that gets the starting address of the memory you want to disassemble, and then calls on the monitor "L" command as long as you like.  The opcode and operand of each disassembled line are packed into a string array until you want to quit.  Then you have the option to write the string array on a text file.  The program squeezes out the two extra spaces mentioned above, and omits the hex address from each line.  In place of the address and blanks which precede the opcode, this program inserts two control-I characters.

Later, when you use EXEC to get the text file into the S-C Assembler II, the first control-I will generate a line number, and the second one will tab over to the opcode column.

To speed it up a little, I wrote a machine language routine to move the second screen line into the string array. I used the last 15 lines of the Field Input Routine from the September, 1981, issue of AAL as a guide.  (Thank you, Bob Potts!)

I chose to not use the already overworked "&" way to call my subroutine.  Instead I just used CALL 768, followed by the string reference.  It works just as well, as far as I'm concerned.

Also, rather than BLOADing such a short little program, I included it as a hexadecimal string inside the Applesoft program.  I used an old technique from B. Lam (Call A.P.P.L.E., many moons ago) for passing the hex code to the monitor and thence into memory.  (It's all in line 50.)

Line 100 sets up my array for 1280 lines.  That's enough for about 2K of code at a time.  Plenty.  Make it bigger if you like.

Lines 110-120 ask for and process the starting memory address you want.  If you type a negative value, I add 65536 to it to make it positive (from 0 thru 65535, rather than -32768 thru 32767).  Then I test the range to make sure you ARE in that range.

Line 130 puts the address where the monitor "L" command wants to find it.

The CALL -418 on line 140 disassembles 20 lines.  Line 150 shuffles the operand field two spaces left.  Then CALL 768A$(X) puts the 11-byte string starting with the first character of the opcode on the second screen line, into A$(X).  CALL -912 on line 180 scrolls the screen up one line, so the next line of disassembly is now on the second screen line.  The process repeats until 20 lines have been processed.

Then you have the choice to continue or not.  If not, you have the option to write A$() on a text file.  If you choose to write it on a file, the file is OPENed, DELETEd, OPENed again, and primed for WRITE.  Why the DELETE and extra OPEN?  So that if the file was already there, it will be replaced with a new one.  If a pre-existing file was longer than my new disassembly, the extra old lines would remain in the file.

You know, once the program is in the string array in text form, you could go ahead and scan it for particular addresses in the operand column.  Then you could replace them with meaningful symbols.  And you could add meaningful labels on lines that are branched to....

[James Church is a special agent for the Northwestern Mutual Life Insurance Agency; he lives in Trumbull, CT.  Article ghost-written and program slightly modified by Bob Sander-Cederlof]
